package cn.zswltech.gruul.biz.service.impl;

import cn.hutool.core.convert.Convert;
import cn.zswltech.gruul.biz.service.DictionaryService;
import cn.zswltech.gruul.biz.service.UserService;
import cn.zswltech.gruul.biz.support.impl.IServiceImpl;
import cn.zswltech.gruul.common.enums.StatusCodeEnum;
import cn.zswltech.gruul.common.result.MSG;
import cn.zswltech.gruul.common.result.Response;
import cn.zswltech.gruul.web.api.util.AccountUtil;
import cn.zswltech.gruul.common.dal.dao.DictionaryDOMapper;
import cn.zswltech.gruul.common.entity.DictionaryDO;
import cn.zswltech.gruul.common.entity.UserDO;
import cn.zswltech.gruul.common.dal.query.DictionaryQuery;
import cn.zswltech.gruul.common.dal.tkmybatis.Page;
import cn.zswltech.gruul.common.dal.vo.AccountVO;
import cn.zswltech.gruul.common.dal.vo.DictionarySave;
import cn.zswltech.gruul.common.dal.vo.DictionaryTO;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Select;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;


@Service("dictionaryServiceAPI")
public class DictionaryServiceImpl extends IServiceImpl<DictionaryDO> implements DictionaryService {
    private final static Logger logger = LoggerFactory.getLogger(DictionaryServiceImpl.class);



    @Resource
    private DictionaryDOMapper dictionaryDOMapper;

    @Resource
    private UserService userService;


    @Override
    @Select("SET GLOBAL group_concat_max_len = 1024000;SET SESSION group_concat_max_len = 1024000")
    public Response<Page<DictionarySave>> getDictionaryList(DictionaryQuery query) {

        PageHelper.startPage(query.getCurPage(),query.getPageSize());
        //query.setStartRow((query.getCurPage()-1) * query.getPageSize());
        List<DictionarySave> dictionarySaveList = dictionaryDOMapper.queryPage(query);
        PageInfo pageInfo = new PageInfo(dictionarySaveList);
        List<String> accountList = dictionarySaveList.stream().map(DictionarySave::getUpdateBy).filter(Objects::nonNull).collect(Collectors.toList());
        Map<String,String> userMap = new HashMap<>();
        if(CollectionUtils.isNotEmpty(accountList)){
            Example example = new Example(UserDO.class);
            example.createCriteria().andIn("account",accountList);
            userMap = userService.selectByExample(example).stream().collect(Collectors.toMap(UserDO::getAccount,UserDO::getUserName));
        }
        for(DictionarySave save : dictionarySaveList){
            List<DictionaryTO> list = Lists.newArrayList();
            if(Objects.isNull(save.getDetail())){
                continue;
            }
            List<String> kv = Arrays.asList(save.getDetail().split("@@"));
            for(String value : kv){
                String[] split = value.split("##");
                if (split.length==2 && !StringUtils.isBlank(split[0]) && !StringUtils.isBlank(split[1])){
                    DictionaryTO e = new DictionaryTO(split[0], split[1]);
                    list.add(e);
                    String dName = (String)e.getDName();

                    if(isJSONString(dName)){
                        try {
                            Object jb = JSON.parse(dName);
                            e.setDName(jb);
                        }catch (Exception ex){
                        }
                    }

                }
            }
            save.setMyValue(list);
            save.setUpdateBy(userMap.get(save.getUpdateBy()));
        }
        Page page = new Page(pageInfo.getTotal(), query.getCurPage(), query.getPageSize(),
                pageInfo.getPages(), pageInfo.getSize(), dictionarySaveList);
        return Response.success(page);
    }

    @Override
    public Response<List<DictionaryDO>> getDictionaryListNoPage(DictionaryQuery query) {
        try {
                List<DictionaryDO> dictionaryDOS = dictionaryDOMapper.queryList(query);
            return Response.success(dictionaryDOS);
        } catch (Exception e) {
            logger.error("API get dictionary list error", e);
        }
        return Response.error(500,"字典查询失败");
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Response createDictionary(DictionarySave dictionarySave) {
        List<DictionaryTO> dictionaryTOList = null;
        if(Objects.nonNull(dictionarySave.getMyValueParams())){
            dictionaryTOList = JSON.parseArray(dictionarySave.getMyValueParams(), DictionaryTO.class);
        }
        if(CollectionUtils.isEmpty(dictionaryTOList)){
            return Response.error(StatusCodeEnum.PARAM_ERROR,"入参myValueParams解析为空");
        }else {
            dictionarySave.setMyValue(dictionaryTOList);
        }

        List<DictionaryDO> insertList = Lists.newArrayList();
        for(DictionaryTO TO : dictionarySave.getMyValue()){
            DictionaryDO dictionaryDO = new DictionaryDO();
            dictionaryDO.setDictDesc(dictionarySave.getDescription());
            dictionaryDO.setDictKey(dictionarySave.getMyKey());
            dictionaryDO.setGmtUpdate(new Date());
            dictionaryDO.setUpdateBy(Optional.ofNullable(AccountUtil.getLoginInfo()).map(AccountVO::getAccount).orElse("system"));

            dictionaryDO.setCode(TO.getName());
            if(TO.getDName() instanceof JSONObject || TO.getDName() instanceof JSONArray){
                dictionaryDO.setDisplay(JSON.toJSONString(TO.getDName()));
            }else {
                dictionaryDO.setDisplay(Convert.convert(String.class,TO.getDName()));
            }
            insertList.add(dictionaryDO);
        }
        dictionaryDOMapper.insertList(insertList);
        return Response.success(null);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Response updateDictionary(DictionarySave dictionarySave) {
        deleteDictionary(dictionarySave.getMyKey());
        createDictionary(dictionarySave);
        return Response.success(null);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Response deleteDictionary(String myKey) {
        Response response = new Response();
        if (myKey == null) {
            response.setMessage(MSG.req_error_param_null, "myKey");
            return response;
        }
        try {
            Example example = new Example(DictionaryDO.class);
            example.createCriteria().andEqualTo("dictKey",myKey);
            int count = dictionaryDOMapper.deleteByExample(example);
            if (count > 0) {
                //Todo 消息通知

                return Response.success(null);
            } else {
                response.setMessage(MSG.req_error_param_invalid, "myKey");
                return response;
            }
        } catch (Exception e) {
            logger.error("API delete dictionary error", e);
            response.setMessage(MSG.old_system_error);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        return response;
    }


    private boolean isJSONString(String str){
        try {
            JSON.parse(str);
            return true;
        }catch(Exception e){
            return false;
        }
    }
}
